import React from 'react';
import { Col, DatePicker, Dropdown, Input, Menu, Row, Select } from 'antd';
import { Form, Icon } from '@ant-design/compatible';
import IconButton from '../IconButton';
import moment from 'moment';
import tools from '../../utils';
import css from './index.css';

const { Option } = Select;

class page extends React.Component {
  state = {
    valueArr: [], // 字段值
    defaultValueArr: [], // 字段默认值
    searchTypeArr: [], // 查询类型
    fieldsNameArr: [], // 字段名
    fieldsTypeArr: [], // 字段类型
    fields3: [],
    fieldCount: 0, // 字段个数
    labelWidth: 72, // 输入框标签宽度
    colSpan: 8, // 输入框宽度占比(最大24)
  };

  componentDidMount() {
    this.funcUpdateDom();
  }

  // 更新dom
  funcUpdateDom = () => {
    const { state, props } = this;
    const { fields } = props;
    if (!fields) return;

    // 只存放带有type属性的字段(筛选)
    const fields2 = [];
    for (let i = 0; i < fields.length; i += 1) {
      const field = fields[i];
      if (field.type) fields2.push(field);
    }

    // 数值输入框和日期选择框分成两个处理
    state.fields3 = [];
    state.fieldCount = 0;
    const mapping = {
      date: '日期',
      datetime: '时间',
    };
    let field = {},
      add = {};
    for (let i = 0; i < fields2.length; i += 1) {
      field = fields2[i];
      switch (field.type) {
        case 'number':
          field.searchType = 'GT';
          state.fields3.push(field);

          add = { ...field };
          add.searchType = 'LT';
          state.fields3.push(add);
          state.fieldCount += 1;
          break;
        case 'date':
        case 'datetime':
          field.title2 = '开始' + mapping[field.type];
          field.searchType = 'GT';
          field.value = field.startTime === '' ? '' :
            field.startTime || tools.funcGetWeek().startDate;
          state.fields3.push(field);
          state.fieldCount += 1;

          add = { ...field };
          add.title2 = '结束' + mapping[field.type];
          add.searchType = 'LT';
          add.value = field.endTime || tools.funcToday() + ' 23:59:59';
          state.fields3.push(add);
          state.fieldCount += 1;
          break;
        case 'dateSingle':
          field.value = field.startTime || tools.funcToday() + ' 00:00:00';
          field.searchType = 'GT';
          state.fields3.push(field);

          add = { ...field };
          add.value = field.endTime || tools.funcToday() + ' 23:59:59';
          add.searchType = 'LT';
          state.fields3.push(add);
          state.fieldCount += 1;
          break;
        case 'month':
          // 月份选择
          field.value = field.startTime || tools.funcGetYYYYMM01() + ' 00:00:00';
          field.searchType = 'GT';
          state.fields3.push(field);

          add = { ...field };
          add.value = field.endTime || tools.funcGetLastMonthDay() + ' 23:59:59';
          add.searchType = 'LT';
          state.fields3.push(add);
          state.fieldCount += 1;
          break;
        case 'week':
          // 周选择
          const week = tools.funcGetWeek();
          field.value = field.startTime || week.startDate;
          field.searchType = 'GT';
          state.fields3.push(field);

          add = { ...field };
          add.value = field.endTime || week.endDate;
          add.searchType = 'LT';
          state.fields3.push(add);
          state.fieldCount += 1;
          break;
        default:
          state.fields3.push(field);
          state.fieldCount += 1;
      }
    }

    switch (state.fieldCount) {
      case 1:
        state.colSpan = 16;
        break;
      case 3:
        state.colSpan = props.showSubmit ? 6 : 8;
        break;
      default:
        state.colSpan = 8;
    }

    // 设置输入框默认值
    state.valueArr = [];
    for (let i = 0; i < state.fields3.length; i += 1) {
      const field = state.fields3[i];
      let value0 = '';
      switch (field.type) {
        case 'number':
          value0 = 0;
          if (field.sub !== undefined) {
            const title = field.title2 || field.title;
            if (title.length >= 6) state.labelWidth = 98;
          }
          break;
        case 'date':
        case 'datetime':
        case 'dateSingle':
        case 'month':
        case 'week':
          value0 = field.value;
          break;
        case 'select':
          value0 =
            field.sub.length >= 2 && field.all !== false
              ? '-1'
              : field.sub[0]
              ? field.sub[0][0]
              : '' || '';
          break;
        default:
          value0 = field.value || '';
      }
      state.valueArr.push(value0);
    }
    state.defaultValueArr = [...state.valueArr];

    this.setState({});
  };

  // 字段值改变
  funcOnChangeValue = (value, index, needSubmit = false, field) => {
    const { props, state } = this;
    const { showSubmit = true, autoSubmit = true } = props;
    state.valueArr[index] = value;
    if (field.onChange) field.onChange(value);
    this.setState({}, () => {
      if ((!showSubmit || needSubmit) && autoSubmit) this.funcSubmit();
    });
  };

  // 提交记录查询的网络请求
  funcSubmit = e => {
    if (e) e.preventDefault();

    const { state, props } = this;
    const { valueArr, searchTypeArr, fieldsNameArr, fieldsTypeArr } = state;
    const arr = [];
    for (let i = 0; i < valueArr.length; i += 1) {
      const value = valueArr[i];
      if (value === '' || value === 0 || value === '-1') {
        // 跳过空和全部
      } else {
        const name = fieldsNameArr[i];
        const searchType = searchTypeArr[i];
        const dataType = fieldsTypeArr[i] === 'number' ? 'NUM' : 'STR';
        const item = { name, value, searchType, dataType };
        arr.push(item);
      }
    }

    if (props.onSubmit) props.onSubmit(arr);
  };

  // 重置(清空输入框的值)
  funcReset = () => {
    const { state } = this;
    const { valueArr, defaultValueArr } = state;
    for (let i = 0; i < valueArr.length; i += 1) valueArr[i] = defaultValueArr[i];
    this.setState({});
  };

  render() {
    const { props, state } = this;
    const { size = 'default', showSubmit = true } = props;
    let { fields3, labelWidth, fieldCount, colSpan } = state;

    const items = []; // 输入框dom
    for (let i = 0; i < fields3.length; i += 1) {
      const field = fields3[i];
      let title = field.title2 || field.title;
      if (field.type === 'number' && field.sub !== undefined) {
        const menuItems = [];
        for (let j = 0; j < field.sub.length; j += 1) {
          const item = field.sub[j];
          menuItems.push(
            <Menu.Item key={j}>
              {
                <span
                  data-field={item[0]}
                  data-index={i}
                  onClick={e => {
                    let index = e.target.getAttribute('data-index');
                    index = parseInt(index, 10);
                    document.getElementById('label' + index).textContent = e.target.textContent;
                    state.fieldsNameArr[index] = e.target.getAttribute('data-field');
                    state.fieldsNameArr[index + 1] = e.target.getAttribute('data-field');
                  }}
                >
                  {' '}
                  {item[1]}
                </span>
              }
            </Menu.Item>
          );
        }
        const menu = <Menu>{menuItems}</Menu>;

        title = (
          <Dropdown overlay={menu}>
            <span>
              <span id={'label' + i} style={{ marginRight: 2 }}>
                {title}
              </span>
              <Icon type="down" />
            </span>
          </Dropdown>
        );
      } else if (window.innerWidth > 768) title += '：';

      let valueHtml = ''; // dom实体
      let searchType0 = 'LK'; // 查询类型默认值
      let addValue = ''; // 附加值
      let opt = [];
      const opts = [];

      switch (field.type) {
        case 'text':
          valueHtml = (
            <table width="100%" id={'searchField_' + field.dataIndex}>
              <tbody>
                <tr>
                  <td width={labelWidth}>
                    <pre className={css.pre}>{title}</pre>
                  </td>
                  <td>
                    <Input
                      value={state.valueArr[i]}
                      maxLength={20}
                      data-index={i}
                      size={size}
                      className="searchFormInput"
                      onChange={e => {
                        // 字段值改变触发的事件
                        const { value } = e.target;
                        let index = e.target.getAttribute('data-index');
                        index = parseInt(index, 10);
                        this.funcOnChangeValue(value, index, false, field);
                      }}
                    />
                  </td>
                </tr>
              </tbody>
            </table>
          );
          break;
        case 'number':
          searchType0 = field.searchType || 'EQ';
          valueHtml = (
            <table width="100%" id={'searchField_' + field.dataIndex}>
              <tbody>
                <tr>
                  <td width={title.length === 3 ? 44 : labelWidth}>{title}</td>
                  <td>
                    <Row>
                      <Col span={11}>
                        <Input
                          value={state.valueArr[i]}
                          type="number"
                          min="0"
                          placeholder="最小值"
                          data-index={i}
                          className={css.min}
                          size={size}
                          onChange={e => {
                            const { value } = e.target;
                            let index = e.target.getAttribute('data-index');
                            index = parseInt(index, 10);
                            this.funcOnChangeValue(value, index, false, field);
                          }}
                        />
                      </Col>
                      <Col span={2}>
                        <Input disabled placeholder="~" className={css.between} size={size} />
                      </Col>
                      <Col span={11}>
                        <Input
                          value={state.valueArr[i + 1]}
                          type="number"
                          min="0"
                          placeholder="最大值"
                          data-index={i + 1}
                          className={css.max}
                          size={size}
                          onChange={e => {
                            const { value } = e.target;
                            let index = e.target.getAttribute('data-index');
                            index = parseInt(index, 10);
                            this.funcOnChangeValue(value, index, false, field);
                          }}
                        />
                      </Col>
                    </Row>
                  </td>
                </tr>
              </tbody>
            </table>
          );
          break;
        case 'date':
          searchType0 = field.searchType || 'EQ';
          addValue = state.valueArr[i] + '_' + i + '_' + searchType0;
          valueHtml = (
            <table width="100%" id={'searchField_' + field.dataIndex}>
              <tbody>
                <tr>
                  <td width={labelWidth}>
                    <pre className={css.pre}>{title}</pre>
                  </td>
                  <td>
                    <DatePicker
                      value={state.valueArr[i] ? moment(addValue, 'YYYY-MM-DD') : null}
                      defaultPickerValue={moment(
                        state.valueArr[i]
                          ? addValue
                          : (searchType0 === 'GT'
                              ? tools.funcGetWeek().startDate
                              : tools.funcToday() + ' 23:59:59') +
                              '_' +
                              i +
                              '_' +
                              searchType0,
                        'YYYY-MM-DD'
                      )}
                      format="YYYY-MM-DD"
                      style={{ width: '100%' }}
                      showToday={false}
                      size={size}
                      allowClear={false}
                      disabledDate={now => now > moment().endOf('day')}
                      onChange={(e, val) => {
                        let index = e._i;
                        index = index.substr(index.indexOf('_') + 1, index.length);
                        index = parseInt(index, 10);
                        let searchType = e._i;
                        searchType = searchType.substr(
                          searchType.lastIndexOf('_') + 1,
                          searchType.length
                        );
                        const value = val + (searchType === 'LT' ? ' 23:59:59' : ' 00:00:00');
                        this.funcOnChangeValue(value, index, true, field);
                      }}
                    />
                  </td>
                </tr>
              </tbody>
            </table>
          );
          break;
        case 'datetime':
          searchType0 = field.searchType || 'EQ';
          addValue = state.valueArr[i] + '_' + i + '_' + searchType0;
          valueHtml = (
            <table width="100%" id={'searchField_' + field.dataIndex}>
              <tbody>
                <tr>
                  <td width={labelWidth}>
                    <pre className={css.pre}>{title}</pre>
                  </td>
                  <td>
                    <DatePicker
                      value={state.valueArr[i] ? moment(addValue, 'YYYY-MM-DD HH:mm') : null}
                      defaultPickerValue={moment(
                        state.valueArr[i]
                          ? addValue
                          : (searchType0 === 'GT'
                              ? tools.funcGetWeek().startDate
                              : tools.funcToday() + ' 23:59:59') +
                              '_' +
                              i +
                              '_' +
                              searchType0,
                        'YYYY-MM-DD HH:mm'
                      )}
                      format="YYYY-MM-DD HH:mm"
                      showTime={{ format: 'HH:mm' }}
                      style={{ width: '100%', minWidth: 'auto' }}
                      showToday={false}
                      size={size}
                      allowClear={false}
                      disabledDate={now => now > moment().endOf('day')}
                      onChange={(e, val) => {
                        let index = e._i;
                        index = index.substr(index.indexOf('_') + 1, index.length);
                        index = parseInt(index, 10);
                        let searchType = e._i;
                        searchType = searchType.substr(
                          searchType.lastIndexOf('_') + 1,
                          searchType.length
                        );
                        let value = val;
                        value = searchType === 'LT' ? value + ':59' : value + ':00';
                        this.funcOnChangeValue(value, index, true, field);
                      }}
                    />
                  </td>
                </tr>
              </tbody>
            </table>
          );
          break;
        case 'dateSingle':
          searchType0 = field.searchType || 'EQ';
          addValue = state.valueArr[i] + '_' + i + '_' + searchType0;
          valueHtml = (
            <table width="100%" id={'searchField_' + field.dataIndex}>
              <tbody>
                <tr>
                  <td width={labelWidth}>
                    <pre className={css.pre}>{title}</pre>
                  </td>
                  <td>
                    <DatePicker
                      value={state.valueArr[i] ? moment(addValue, 'YYYY-MM-DD') : null}
                      defaultPickerValue={moment(
                        state.valueArr[i]
                          ? addValue
                          : (searchType0 === 'GT'
                              ? tools.funcGetWeek().startDate
                              : tools.funcToday() + ' 23:59:59') +
                              '_' +
                              i +
                              '_' +
                              searchType0,
                        'YYYY-MM-DD'
                      )}
                      format="YYYY-MM-DD"
                      style={{ width: '100%' }}
                      showToday={false}
                      size={size}
                      allowClear={false}
                      disabledDate={now => now > moment().endOf('day')}
                      onChange={(e, val) => {
                        let index = e._i;
                        index = index.substr(index.indexOf('_') + 1, index.length);
                        index = parseInt(index, 10);
                        this.funcOnChangeValue(val + ' 00:00:00', index, false, field);
                        this.funcOnChangeValue(val + ' 23:59:59', index + 1, true, field);
                      }}
                    />
                  </td>
                </tr>
              </tbody>
            </table>
          );
          break;
        case 'month':
          // 月份选择
          searchType0 = field.searchType || 'EQ';
          addValue = state.valueArr[i] + '_' + i + '_' + searchType0;
          valueHtml = (
            <table width="100%" id={'searchField_' + field.dataIndex}>
              <tbody>
                <tr>
                  <td width={labelWidth}>
                    <pre className={css.pre}>{title}</pre>
                  </td>
                  <td>
                    <DatePicker.MonthPicker
                      defaultValue={moment(addValue, 'YYYY-MM-DD')}
                      format="M月"
                      style={{ width: '100%' }}
                      size={size}
                      allowClear={false}
                      disabledDate={now => now > moment().endOf('day')}
                      onChange={(e) => {
                        let index = e._i;
                        index = index.substr(index.indexOf('_') + 1, index.length);
                        index = parseInt(index, 10);
                        const d = new Date(e._d);
                        const yy = d.getFullYear();
                        let mm = d.getMonth() + 1;
                        mm = mm < 10 ? '0' + mm : mm;
                        const value = yy + '-' + mm + '-01';
                        const value2 = tools.funcGetLastMonthDay(value);
                        this.funcOnChangeValue(value + ' 00:00:00', index, false, field);
                        this.funcOnChangeValue(value2 + ' 23:59:59', index + 1, true, field);
                      }}
                    />
                  </td>
                </tr>
              </tbody>
            </table>
          );
          break;
        case 'week':
          // 周选择
          searchType0 = field.searchType || 'EQ';
          addValue = state.valueArr[i] + '_' + i + '_' + searchType0;
          valueHtml = (
            <table width="100%" id={'searchField_' + field.dataIndex}>
              <tbody>
                <tr>
                  <td width={labelWidth}>
                    <pre className={css.pre}>{title}</pre>
                  </td>
                  <td>
                    <DatePicker.WeekPicker
                      defaultValue={moment(addValue, 'YYYY-MM-DD')}
                      style={{ width: '100%' }}
                      size={size}
                      allowClear={false}
                      disabledDate={now => now > moment().endOf('day')}
                      onChange={(e) => {
                        let index = e._i;
                        index = index.substr(index.indexOf('_') + 1, index.length);
                        index = parseInt(index, 10);
                        const d = new Date(e._d);
                        const yy = d.getFullYear();
                        let mm = d.getMonth() + 1;
                        let dd = d.getDate();
                        mm = mm < 10 ? '0' + mm : mm;
                        dd = dd < 10 ? '0' + dd : dd;
                        const value = yy + '-' + mm + '-' + dd;
                        const week = tools.funcGetWeek(value);
                        this.funcOnChangeValue(week.startDate, index, false, field);
                        this.funcOnChangeValue(week.endDate, index + 1, true, field);
                      }}
                    />
                  </td>
                </tr>
              </tbody>
            </table>
          );
          break;
        case 'select':
          searchType0 = 'EQ';
          if (!field.sub) field.sub = [];
          if (field.sub.length >= 2 && field.all !== false) {
            opts.push(
              <Option data-index={i} key='-1' value='-1'>
                全部
              </Option>
            );
          }
          for (let j = 0; j < field.sub.length; j += 1) {
            opt = field.sub[j];
            opts.push(
              <Option data-index={i} key={opt[0]} value={opt[0]}>
                {opt[1]}
              </Option>
            );
          }
          const params = {};
          if (state.valueArr[i] !== '') params.value = state.valueArr[i];
          valueHtml = (
            <table width="100%" id={'searchField_' + field.dataIndex}>
              <tbody>
                <tr>
                  <td width={labelWidth}>
                    <pre className={css.pre}>{title}</pre>
                  </td>
                  <td>
                    <Select
                      {...params}
                      placeholder="暂无数据"
                      style={{ width: '100%' }}
                      size={size}
                      onChange={(value, e) => {
                        const index = e.props['data-index'];
                        this.funcOnChangeValue(value, index, true, field);
                      }}
                    >
                      {opts}
                    </Select>
                  </td>
                </tr>
              </tbody>
            </table>
          );
          break;
        default:
          break;
      }

      state.searchTypeArr.push(searchType0);
      state.fieldsNameArr.push(field.dataIndex);
      state.fieldsTypeArr.push(field.type);

      const item = (
        <Col lg={colSpan} md={12} sm={12} xs={24} key={i}>
          <Form.Item className={css.formItem}>{valueHtml}</Form.Item>
        </Col>
      );

      // 防止重复添加输入框
      if (
        (i && (field.type === 'number' && field.dataIndex === fields3[i - 1].dataIndex)) ||
        (field.type === 'dateSingle' && field.dataIndex === fields3[i - 1].dataIndex) ||
        (field.type === 'month' && field.dataIndex === fields3[i - 1].dataIndex) ||
        (field.type === 'week' && field.dataIndex === fields3[i - 1].dataIndex)
      ) {
        // 忽略
      } else items.push(item);
    }

    let colCount = 0; // 控制一行显示colMax个输入框
    let colMax = window.isPad ? 2 : 3;
    if (fieldCount === 3 && showSubmit) colMax = 4;
    const rows = [];
    let cols = []; // 存放Row, Col
    for (let i = 0; i < items.length; i += 1) {
      cols.push(items[i]);
      colCount += 1;

      if (colCount >= colMax) {
        colCount = 0;
        rows.push(
          <Row gutter={{ xl: 48, lg: 24, md: 8, sm: 8 }} key={i + 100}>
            {cols}
          </Row>
        );
        cols = [];
      }

      // 最后一行的输入框数量可能小于colMax, 会造成最后一行不显示, 这里予以修正
      if (i === items.length - 1) {
        colSpan = items.length === 3 ? 6 : 8;

        if (items.length === 4 || (window.isPad && items.length % 2 === 0)) {
          // 确保查询按钮显示在右边(右对齐)
          cols.push(<Col lg={colSpan} md={12} sm={12} xs={24} key="nullCol" />);
        } else if (items.length === 6) {
          colSpan = 24; // 查询按钮独占一行
        }

        // 查询按钮
        const btn = (
          <Col lg={colSpan} md={12} sm={12} xs={24} key={i + 200} style={{ textAlign: 'right' }}>
            <Form.Item className={css.formItem}>
              <IconButton text='查询' htmlType='submit' size={size} style={{ marginRight: 8 }} />
              {
                items.length <= 3 ? null : (
                  <IconButton
                    text='重置'
                    type='default'
                    htmlType='reset'
                    size={size}
                    onClick={this.funcReset}
                  />
                )
              }
            </Form.Item>
          </Col>
        );

        if (showSubmit) cols.push(btn);
        rows.push(
          <Row gutter={{ xl: 48, lg: 24, md: 8, sm: 8 }} key={i + 300}>
            {cols}
          </Row>
        );
      }
    }

    return <Form onSubmit={this.funcSubmit}>{rows}</Form>;
  }
}

export default page;
